#include <iostream>

using namespace std;

class Phone {
public:
    virtual ~Phone() = default;

public:
    virtual void watchVideo() = 0;
};

class Computer {
public:
    virtual ~Computer() = default;

public:
    virtual void playGame() = 0;
};

class TV {
public:
    virtual ~TV() = default;

public:
    virtual void watchTV() = 0;
};

class Factory {
public:
    virtual ~Factory() = default;

public:
    virtual Phone *createPhone() = 0;

    virtual Computer *createComputer() = 0;

    virtual TV *createTV() = 0;
};

class FactoryAdapterTV : public Factory {
public:
    ~FactoryAdapterTV() override = default;

private:
    TV *createTV() override {
        return nullptr;
    }
};


class PhoneA : public Phone {
public:
    ~PhoneA() override = default;

public:
    void watchVideo() override {
        cout << "Phone A Watch Video!" << endl;
    }
};

class PhoneB : public Phone {
public:
    ~PhoneB() override = default;

public:
    void watchVideo() override {
        cout << "Phone B Watch Video!" << endl;
    }
};

class ComputerA : public Computer {
public:
    ~ComputerA() override = default;

public:
    void playGame() override {
        cout << "Computer A Play Game!" << endl;
    }
};

class ComputerB : public Computer {
public:
    ~ComputerB() override = default;

public:
    void playGame() override {
        cout << "Computer B Play Game!" << endl;
    }
};

class TVA : public TV {
public:
    ~TVA() override = default;

public:
    void watchTV() override {
        cout << "TV A Watch TV" << endl;
    }
};

class FactoryA : public Factory {
public:
    ~FactoryA() override = default;

public:
    Phone *createPhone() override {
        Phone *instance = nullptr;
        instance = new PhoneA();
        return instance;
    }

    Computer *createComputer() override {
        Computer *instance = nullptr;
        instance = new ComputerA();
        return instance;
    }

    TV *createTV() override {
        TV *instance = nullptr;
        instance = new TVA();
        return instance;
    }
};

class FactoryB : public FactoryAdapterTV {
public:
    ~FactoryB() override = default;

public:
    Phone *createPhone() override {
        Phone *instance = nullptr;
        instance = new PhoneB();
        return instance;
    }

    Computer *createComputer() override {
        Computer *instance = nullptr;
        instance = new ComputerB();
        return instance;
    }
};

void test01() {
    Phone *phone = nullptr;
    Computer *computer = nullptr;
    TV *tv = nullptr;
    Factory *factory = nullptr;

    factory = new FactoryA();
    phone = factory->createPhone();
    computer = factory->createComputer();
    tv = factory->createTV();

    phone->watchVideo();
    computer->playGame();
    tv->watchTV();

    delete phone, computer, tv, factory;

    cout << endl;
}

void test02() {
    Phone *phone = nullptr;
    Computer *computer = nullptr;
    FactoryAdapterTV *factory = nullptr;

    factory = new FactoryB();
    phone = factory->createPhone();
    computer = factory->createComputer();

    phone->watchVideo();
    computer->playGame();

    delete phone, computer, factory;

    cout << endl;
}


int main() {
    test01();

    test02();
}
